﻿#coding: utf-8

import Primitives
import Properties
from Graphics import *

from Units import Curve,Snake
from Util import Point
from Constants import *

class CurveEntitie(Primitives.GameObject):

	def __init__(self,id):
		super(CurveEntitie,self).__init__(id,CurveEventManager())
		
		self.image, self.rect = load_surface_from_image(Properties.imgCurva)
		
		self._real_image = self.image.copy()	
		self._real_curve_image = None
		
		self.unit = Curve(self.image.get_size())

		self._mouse_pos1 = 0
		self._mouse_pos2 = 0
		
		self._draw_curve_state = False
		self._automatic_draw = False
		
		
	def update(self):			
		if self._automatic_draw:
			return 
		
		if self._draw_curve_state:
			mouse_pos1 = self.get_relative_image_mouse_position(self._mouse_pos1[0],self._mouse_pos1[1])
			mouse_pos2 = self.get_relative_image_mouse_position(self._mouse_pos2[0],self._mouse_pos2[1])

			if mouse_pos1[0] is not None and mouse_pos2[1] is not None:
				self.unit.add_rect( mouse_pos1,mouse_pos2 )
				r = desenhar_reta_curva( mouse_pos1,mouse_pos2,self.image,Colors.RED )			
			
			self._mouse_pos1,self._mouse_pos2 = self._mouse_pos2,pygame.mouse.get_pos()

	def go_draw(self):
		self.image = self._real_image.copy()
		self.unit = Curve(self.image.get_size())
		self._draw_curve_state = True

		self._mouse_pos1 = pygame.mouse.get_pos()
		self._mouse_pos2 = pygame.mouse.get_pos()

		
		if self._automatic_draw:
			test_points = [  ( 151 , 28 ) , ( 140 , 33 ) , ( 134 , 31 ) , ( 133 , 21 ) , ( 128 , 13 ) , ( 118 , 16 ) , ( 108 , 21 ) , ( 97 , 25 ) , ( 86 , 26 ) , ( 83 , 18 ) , ( 79 , 10 ) , ( 71 , 15 ) , ( 60 , 22 ) , ( 50 , 29 ) , ( 48 , 22 ) , ( 43 , 24 ) , ( 35 , 36 ) , ( 26 , 46 ) , ( 24 , 52 ) , ( 22 , 63 ) , ( 18 , 75 ) , ( 16 , 86 ) , ( 13 , 98 ) , ( 12 , 109 ) , ( 12 , 120 ) , ( 14 , 131 ) , ( 17 , 142 ) , ( 25 , 148 ) , ( 36 , 142 ) , ( 39 , 144 ) , ( 39 , 154 ) , ( 48 , 158 ) , ( 59 , 152 ) , ( 71 , 145 ) , ( 83 , 138 ) , ( 95 , 132 ) , ( 98 , 137 ) , ( 100 , 146 ) , ( 111 , 142 ) , ( 123 , 137 ) , ( 135 , 132 ) , ( 147 , 127 ) , ( 157 , 126 ) , ( 158 , 135 ) , ( 163 , 136 ) , ( 174 , 127 ) , ( 183 , 122 ) , ( 191 , 115 ) , ( 200 , 110 ) , ( 209 , 101 ) , ( 213 , 91 ) , ( 213 , 81 ) , ( 213 , 71 ) , ( 210 , 61 ) , ( 205 , 51 ) , ( 196 , 42 ) , ( 186 , 35 ) , ( 175 , 33 ) , ( 167 , 31 )   ]
			
			pi = test_points[0]
			p1 = pi
			for i in range( 1,len(test_points) ):
				p2 = test_points[i]
				
				self.unit.add_rect( p1,p2,True )
				r = desenhar_reta_curva( p1,p2,self.image,Colors.RED )	
				
				p1 = p2
				
			r = desenhar_reta_curva( p2,pi,self.image,Colors.RED )	
		
		self.real_curve_image = self.image.copy()
		
		
	def stop_draw(self):
		self._draw_curve_state = False
		
		self._mouse_pos1 = 0
		self._mouse_pos2 = 0		
		
		self.reset_image()
		self.unit.draw_curve(self.image)
		
		self._real_curve_image = self.image.copy()
		
	def reset_image(self):
		self.image = self._real_image.copy()
		
	def get_relative_image_mouse_position(self,mousex,mousey):
		
		if( ( mousex<self.rect.x or mousex>(self.rect.x+self.rect.width) ) or
			( mousey<self.rect.y or mousey>self.rect.y+self.rect.height) ):
			
			return (None,None)
		else:
			return ( (mousex - self.rect.x ),(mousey-self.rect.y) )
			
class CurveEventManager(Primitives.EventManager):

	def fireEvent(self,scene,go,event):
		if event.type == MOUSEBUTTONDOWN and go.rect.collidepoint(event.pos):
			if not scene.Snake.is_initialized():
				scene.Snake._is_visible = False
				go._is_visible = True
				
				go.go_draw();
			
		elif event.type == MOUSEBUTTONUP and go.rect.collidepoint(event.pos):
			if not scene.Snake.is_initialized():
				go.stop_draw()	
				scene.Snake.set_curve( go )
		
				#print scene.Curve.unit.print_points()
			

class SnakeEntitie(Primitives.GameObject):
	
	CONTINUO = 0
	STEP_BY_STEP = 1
	
	def __init__(self,id):
		super(SnakeEntitie,self).__init__(id,SnakeEventManager())
		
		self.image, self.rect = None,None
		self.backsurface = None
		
		self.unit = None
				
		self._str_index = ""
		self._minimize_flag = False
		self._update_flag = False
		self._show_dir_pt_linear = True
				
		self._mode = SnakeEntitie.CONTINUO	

		self.ptSelected = None
		
	def is_initialized(self):
		if self.unit is not None:
			return True
		else:
			return False
		
	def is_started(self):
		if self.unit is not None:
			return self._minimize_flag
		else:
			return False
		
	def is_looping(self):
		return self._minimize_flag
		
	def start(self):
		self._minimize_flag = True
		self.unit.start()
		
	def restart(self):
		self._minimize_flag = True
		
	def stop(self):
		self.unit = None
		self.pause()
		
	def pause(self):
		self._minimize_flag = False
		
	def go_back(self,index):
		self.unit.go_back(index)
		self._update_flag = True
		
	def toogle_mode(self):
		if self._mode == SnakeEntitie.STEP_BY_STEP:
			self._mode = SnakeEntitie.CONTINUO
		else:
			self._mode = SnakeEntitie.STEP_BY_STEP
		
	def input(self,unicode):
		self._str_index += unicode
		
	def set_curve(self,curve):
		self.unit = Snake(load_image(Properties.imgCurva),curve.unit)				
		self._str_index = ""
		
		self.image = curve.image		
		self.rect = curve.rect
		
		self.backsurface = curve.image.copy()
		
	def setar_quina(self):
		self.unit.xk.pontos[ ( int(self._str_index) ) ].quina = not ( self.unit.xk.pontos[ ( int(self._str_index) ) ].quina )
		self._str_index = ""
		
	def set_manual_alfa(self):
		indice = int( self._str_index.split(",")[0] )
		coef = self._str_index.split(",")[1]
		
		self.unit.set_manual_alfa( indice,float( coef ) )
		self._str_index = ""
		
	def set_manual_beta(self):
		indice = int( self._str_index.split(",")[0] )
		coef = self._str_index.split(",")[1]
		
		self.unit.set_manual_beta( indice,float( coef ) )
		self._str_index = ""		
		
	def set_manual_gama(self):
		indice = int( self._str_index.split(",")[0] )
		coef = self._str_index.split(",")[1]
		
		self.unit.set_manual_gama( indice,float( coef ) )
		self._str_index = ""	

	def set_manual_delta(self):
		indice = int( self._str_index.split(",")[0] )
		coef = self._str_index.split(",")[1]
		
		self.unit.set_manual_delta( indice,float( coef ) )
		self._str_index = ""		
		
		
	def update(self):

		if self._update_flag:
			img = self.backsurface.copy()
			
			pi = self.unit.pontos[0]
			p1 = pi

			for i in range(1,len(self.unit.pontos) ):
				p2 = self.unit.pontos[i]
				
				desenhar_reta_snake( p1,p2,img,Colors.GREEN )
				
				p1 = p2
				
				
				if self._show_dir_pt_linear:
					p_teste_1 = p1								
					p_teste_2 = Point( p_teste_1.x+10*p_teste_1.dir_pt_linear.x,p_teste_1.y+10*p_teste_1.dir_pt_linear.y,0)
					p_teste_2.cor = Colors.BLACK
					desenhar_reta_snake( p_teste_1,p_teste_2,img,Colors.GREEN )
				
				
				'''
				if p1.index < 4:
					p_teste_1 = p1								
					p_teste_2 = Point( p_teste_1.x+20*p_teste_1.dir_pt_linear.x,p_teste_1.y+20*p_teste_1.dir_pt_linear.y,0)
					p_teste_2.cor = Colors.BLACK
					desenhar_reta_snake( p_teste_1,p_teste_2,img,Colors.GREEN )
					
					p_teste_1 = p1								
					p_teste_2 = Point( p_teste_1.x+20*p_teste_1.check_vector.x,p_teste_1.y+20*p_teste_1.check_vector.y,0)
					p_teste_2.cor = Colors.BLUE
					desenhar_reta_snake( p_teste_1,p_teste_2,img,Colors.ORANGE )					
				'''
										
				
			if self.ptSelected is not None:
				self.ptSelected = self.unit.pontos[self.ptSelected.index]
				self.ptSelected.color = Colors.CIAN
				
				desenhar_reta_snake( self.ptSelected,self.ptSelected,img,Colors.GREEN )
				
			desenhar_reta_snake( p2,pi,img,Colors.GREEN )
			desenhar_reta_snake( self.unit.ponto_medio,self.unit.ponto_medio,img,Colors.PINK )
						
						
			self.image = img
			
			pygame.event.post( pygame.event.Event(USEREVENT,{"userType":"Update"} ) )

			#salvar_imagem( self.unit.img,Properties.imgTemp )
			
			'''
			img_d = ImageDebug.get_instance(img)
			img_d.print_image()
							
			salvar_imagem( img_d.surf, Properties.imgDebug )			
			'''
			
		self._update_flag = False
		
	def minimize(self):
		self.unit.minimizar()
		if self._mode == SnakeEntitie.STEP_BY_STEP:
			self.pause()
		
		self._update_flag = True
		
	def print_debug(self):
		self.unit.debug.imprimir()
		
class SnakeEventManager(Primitives.EventManager):

	def fireEvent(self,scene,go,event):
		if event.type == KEYDOWN and event.key == K_l:
			go._show_dir_pt_linear = not go._show_dir_pt_linear	
		
		elif event.type == MOUSEBUTTONDOWN:
			if go.is_initialized() and go.rect.collidepoint(event.pos):
				x_rel = event.pos[0] - go.rect.x
				y_rel = event.pos[1] - go.rect.y
				
				for pt in go.unit.pontos:
					if (int(pt.x) >= x_rel and int(pt.x) <=(x_rel+1) ) and ( int(pt.y) >= y_rel and int(pt.y)<=(y_rel+1) ) :	
						if go.ptSelected is not None:
							go.ptSelected.color = pt.color
						go.ptSelected = pt
						
						go.ptSelected.color = Colors.CIAN						
						go._update_flag = True
						break
						
		elif event.type == KEYDOWN and ( event.key == K_RIGHT or event.key == K_LEFT ):
			if go.is_initialized():
				fat = event.key - K_RIGHT
				fat*=2
				fat-=1
				
				pt = go.unit.pontos[go.ptSelected.index+fat]
				if go.ptSelected is not None:				
					go.ptSelected.color = pt.color
					
				go.ptSelected = pt				
				go.ptSelected.color = Colors.CIAN						
				go._update_flag = True					
			
		
		elif event.type == USEREVENT and event.userType=="Update":		
			scene.lblValueIteracao.label = str(go.unit.iteracao)
			scene.lblValueIteracao.pack()
			
			if go.ptSelected is not None:
				scene.lblValuePtSelected.label = str(go.ptSelected.index)
				scene.lblValuePtSelected.pack()
				
				scene.lblValuePtDirection.label = "(%.3f,%.3f)" % ( go.unit.dk.points[go.ptSelected.index].x,go.unit.dk.points[go.ptSelected.index].y )
				scene.lblValuePtDirection.pack()
				
				scene.lblValuePtLinearDirection.label = "(%.3f,%.3f)" % ( go.ptSelected.dir_pt_linear.x,go.ptSelected.dir_pt_linear.y )
				scene.lblValuePtLinearDirection.pack()			
				
				scene.lblValuePtContinuity.label = "(%.3f,%.3f)" % ( go.ptSelected.comp_continuidade[0],go.ptSelected.comp_continuidade[1] )
				scene.lblValuePtContinuity.pack()
				
				scene.lblValuePtSuavity.label = "(%.3f,%.3f)" % ( go.ptSelected.comp_suavidade[0],go.ptSelected.comp_suavidade[1] ) 
				scene.lblValuePtSuavity.pack()
				
				scene.lblValuePtColor.label = "(%.3f,%.3f)" % ( go.ptSelected.comp_cor[0],go.ptSelected.comp_cor[1] )  
				scene.lblValuePtColor.pack()
				
				scene.lblValuePtGradContinuity.label = "(%.3f,%.3f)" % ( go.ptSelected.grad_comp_continuidade[0],go.ptSelected.grad_comp_continuidade[1] )
				scene.lblValuePtGradContinuity.pack()
				
				scene.lblValuePtGradSuavity.label = "(%.3f,%.3f)" % ( go.ptSelected.grad_comp_suavidade[0],go.ptSelected.grad_comp_suavidade[1] ) 
				scene.lblValuePtGradSuavity.pack()
				
				scene.lblValuePtGradColor.label = "(%.3f,%.3f)" % ( go.ptSelected.grad_comp_cor[0],go.ptSelected.grad_comp_cor[1] )  
				scene.lblValuePtGradColor.pack()			
				
				scene.lblValuePtAlfa.label = "%.3f" % (go.ptSelected.alfa)
				scene.lblValuePtAlfa.pack()
							
				scene.lblValuePtBeta.label = "%.3f" % (go.ptSelected.beta)
				scene.lblValuePtBeta.pack()
				
				scene.lblValuePtGama.label = "(%.3f,%.3f)" % (go.ptSelected.gama[0],go.ptSelected.gama[1])
				scene.lblValuePtGama.pack()

			
			
			scene.lblValueFuncional.label = "%.3f" % (go.unit.funcional)
			scene.lblValueFuncional.pack()
			
			scene.lblValueContinuity.label = "(%.3f,%.3f)" % (go.unit.comp_continuidade[0],go.unit.comp_continuidade[1])
			scene.lblValueContinuity.pack()
			
			scene.lblValueSuavity.label = "(%.3f,%.3f)" % (go.unit.comp_suavidade[0],go.unit.comp_suavidade[1])
			scene.lblValueSuavity.pack()
			
			scene.lblValueColor.label = "(%.3f,%.3f)" % (go.unit.comp_cor[0],go.unit.comp_cor[1])
			scene.lblValueColor.pack()
			
			scene.lblValueLambda.label = str(go.unit.lbda)
			scene.lblValueLambda.pack()

			